package com.example.everying.service.chat.impl;


import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.everying.constant.ChatMessageConstant;
import com.example.everying.mapper.chat.ChatMessagesMapper;
import com.example.everying.mapper.content.ActivityApplyMapper;
import com.example.everying.mapper.content.ActivityArticleMapper;
import com.example.everying.mapper.content.ActivityCommentMapper;
import com.example.everying.mapper.order.TransferRecordMapper;
import com.example.everying.model.dto.chat.ChatMessagePageDto;
import com.example.everying.model.dto.chat.LocationDto;
import com.example.everying.model.dto.content.ActivityArticleDto;
import com.example.everying.model.entity.chat.ChatMessagesEntity;
import com.example.everying.model.entity.content.ActivityApply;
import com.example.everying.model.entity.content.ActivityComment;
import com.example.everying.model.entity.user.UserEntity;
import com.example.everying.model.vo.chat.ChatCommentMessageVo;
import com.example.everying.model.vo.chat.ChatMessageVo;
import com.example.everying.service.chat.ChatMessagesService;
import com.example.everying.service.user.UserService;
import com.example.everying.utils.CampusException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ChatMessagesServiceImpl extends ServiceImpl<ChatMessagesMapper, ChatMessagesEntity> implements ChatMessagesService {
    @Autowired
    private UserService userService;
    @Autowired
    private ChatMessagesMapper chatMessagesMapper;
    @Autowired
    private ActivityApplyMapper activityApplyMapper;
    @Autowired
    private ActivityCommentMapper activityCommentMapper;
    @Autowired
    private ActivityArticleMapper activityArticleMapper;
    @Autowired
    private TransferRecordMapper transferRecordMapper;


    public boolean validateRecallPermission(Long messageId, String userId) {
        ChatMessagesEntity msg = baseMapper.selectById(messageId);
        if (msg == null) {
            throw new CampusException("消息不存在", 201);
        }
        log.info("用户ID:{},发送人ID:{}", userId, msg.getFormUserId());
        // 撤回条件：1. 发送者本人 2. 在允许撤回时间内（2分钟内）
        boolean canRecall = msg.getFormUserId().equals(userId) && ChronoUnit.MINUTES.between(msg.getTime(), LocalDateTime.now()) <= 2;

        if (!canRecall) {
            throw new CampusException("无权撤回该消息", 201);
        }
        return canRecall;
    }

    /**
     * 获取会话的消息列表（分页） 不包含评论消息
     */
    @Override
    public List<ChatMessageVo> getMessageList(ChatMessagePageDto query) {
        Page<ChatMessagesEntity> pageParam = new Page<>(query.getPage(), query.getLimit());
        // 获取当前用户信息
        UserEntity user = userService.getUserById(query.getUserId());
        if (user == null) {
            throw new CampusException("用户不存在", 201);
        }

        // 1. 构建查询条件
        LambdaQueryWrapper<ChatMessagesEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByDesc(ChatMessagesEntity::getTime);
        if (query.getConversationId() != null) {
            wrapper.eq(ChatMessagesEntity::getConversationId, query.getConversationId());
        }
        if (query.getMessagesType() != null) {
            wrapper.eq(ChatMessagesEntity::getMessagesType, query.getMessagesType());
        }
        // 2. 分页查询
        IPage<ChatMessagesEntity> page = chatMessagesMapper.selectPage(pageParam, wrapper);
        // 获取用户id
        Set<String> userIds = new HashSet<>();
        page.getRecords().forEach(chatMessagesEntity -> {
            Optional.ofNullable(chatMessagesEntity.getFormUserId()).ifPresent(userIds::add);
            Optional.ofNullable(chatMessagesEntity.getToUserId()).ifPresent(userIds::add);
        });
        List<UserEntity> userList = userService.listByIds(userIds);
        Map<String, UserEntity> userMap = new HashMap<>();
        userList.forEach(userEntity -> userMap.put(userEntity.getId(), userEntity));

        // 3. 构建 DTO
        List<ChatMessageVo> records = new ArrayList<>();
        page.getRecords().forEach(chatMessagesEntity -> {
            ChatMessageVo chatMessageVo = buildDTO(chatMessagesEntity, userMap);
            chatMessageVo.setSender(chatMessagesEntity.getFormUserId().equals(user.getId()));
            records.add(chatMessageVo);
        });

        return records;
    }

    /**
     * 构建聊天消息VO对象
     * 将ChatMessagesEntity实体转换为ChatMessageVo对象，并填充发送者和接收者信息
     *
     * @param entity  聊天消息实体对象
     * @param userMap 用户信息映射，key为用户ID，value为用户实体
     * @return 转换后的聊天消息VO对象
     */
    private ChatMessageVo buildDTO(ChatMessagesEntity entity, Map<String, UserEntity> userMap) {
        ChatMessageVo dto = new ChatMessageVo();
        dto.setId(entity.getId());
        dto.setContent(entity.getPostMessages());
        dto.setSenderId(entity.getFormUserId());
        dto.setReceiverId(entity.getToUserId());
        dto.setSendTime(entity.getTime());
        dto.setStatus(entity.getMsgStatus());
        dto.setMessageType(entity.getMessagesType());
        dto.setType(entity.getType());
        dto.setMsgStatus(entity.getMsgStatus());
        dto.setBizId(entity.getBizId());
        dto.setIsDelete(entity.getIsDelete());

        // 设置发送者和接收者信息
        dto.setSenderInfo(userMap.get(entity.getFormUserId()));
        dto.setReceiverInfo(userMap.get(entity.getToUserId()));
        switch (entity.getMessagesType()) {
            case ChatMessageConstant.MESSAGE_TYPE_ACTIVITY_LOCATION:
                LocationDto locationDto = JSON.parseObject(entity.getLocationInfo(), LocationDto.class);
                dto.setLocationInfo(locationDto);
                break;
            case ChatMessageConstant.MESSAGE_TYPE_ACTIVITY_TRANSFER:
                dto.setRecord(transferRecordMapper.selectById(entity.getBizId()));
                break;
            case ChatMessageConstant.MESSAGE_TYPE_ACTIVITY_CARD:
                ActivityArticleDto articleDto = JSON.parseObject(entity.getCardInfo(), ActivityArticleDto.class);
                dto.setCardInfo(articleDto);
                break;
        }
        return dto;
    }


    /**
     * 获取会话的消息列表（分页） 评论消息
     */
    @Override
    public ChatCommentMessageVo getCommentMessageList(ChatMessagePageDto query) {
        Page<ChatMessagesEntity> pageParam = new Page<>(query.getPage(), query.getLimit());
        // 获取当前用户信息
        UserEntity user = userService.getUserById(query.getUserId());
        if (user == null) {
            throw new CampusException("用户不存在", 201);
        }

        // 1. 构建查询条件
        LambdaQueryWrapper<ChatMessagesEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByDesc(ChatMessagesEntity::getTime);
        wrapper.ne(ChatMessagesEntity::getMsgStatus, ChatMessageConstant.MESSAGE_STATUS_RECALL);
        if (user.getId() != null) {
            wrapper.eq(ChatMessagesEntity::getToUserId, user.getId());
        }
        if (query.getConversationId() != null) {
            wrapper.eq(ChatMessagesEntity::getConversationId, query.getConversationId());
        }
        if (query.getMessagesType() != null) {
            wrapper.eq(ChatMessagesEntity::getMessagesType, query.getMessagesType());
        }

        // 2. 分页查询
        IPage<ChatMessagesEntity> page = chatMessagesMapper.selectPage(pageParam, wrapper);

        List<ChatMessageVo> messages = new ArrayList<>();
        page.getRecords().forEach(chatMessagesEntity -> {
            ChatMessageVo chatMessageVo = convertToDTO(chatMessagesEntity);
            if (chatMessageVo.getCommentVo() != null) { // 只保留评论信息不为空的记录
                chatMessageVo.setSender(chatMessagesEntity.getFormUserId().equals(user.getId()));
                messages.add(chatMessageVo);
            }
        });

        ChatCommentMessageVo vo = new ChatCommentMessageVo();
        vo.setChatMessageVos(messages);
        List<String> messageIds = new ArrayList<>();
        int unreadCount = 0;
        for (ChatMessageVo message : messages) {
            if (message.getStatus().equals(ChatMessageConstant.MESSAGE_STATUS_UNREAD)) {
                messageIds.add(message.getId());
                unreadCount++;
            }
        }
        vo.setUnreadCount(unreadCount);
        // 异步把未读的信息改成已读
        asyncUpdateMessageStatus(user.getId(), messageIds);
        return vo;
    }

    protected void asyncUpdateMessageStatus(String userId, List<String> messageIds) {
        if (userId.isEmpty()) {
            return;
        }
        UpdateWrapper<ChatMessagesEntity> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("msg_status", ChatMessageConstant.MESSAGE_STATUS_READ);
        updateWrapper.eq("to_user_id", userId);
        updateWrapper.eq("messages_type", ChatMessageConstant.MESSAGE_TYPE_ACTIVITY_COMMENT);
        updateWrapper.eq("msg_status", ChatMessageConstant.MESSAGE_STATUS_UNREAD);
//        if (!messageIds.isEmpty() && messageIds.size() > 1) {
//            updateWrapper.in("id", messageIds);
//        } else if (messageIds.size() == 1) {
//            updateWrapper.eq("id", messageIds.get(0));
//        }
        chatMessagesMapper.update(updateWrapper);
    }

    @Override
    public ChatMessageVo convertToDTO(ChatMessagesEntity entity) {
        ChatMessageVo dto = new ChatMessageVo();
        dto.setId(entity.getId());
        dto.setContent(entity.getPostMessages());
        dto.setSenderId(entity.getFormUserId());
        dto.setReceiverId(entity.getToUserId());
        dto.setSendTime(entity.getTime());
        dto.setStatus(entity.getMsgStatus());
        dto.setMessageType(entity.getMessagesType());
        dto.setType(entity.getType());
        dto.setMsgStatus(entity.getMsgStatus());
        dto.setBizId(entity.getBizId());
        dto.setIsDelete(entity.getIsDelete());

        dto.setSenderInfo(userService.getUserById(entity.getFormUserId()));
        dto.setReceiverInfo(userService.getUserById(entity.getToUserId()));
        switch (entity.getMessagesType()) {
            case ChatMessageConstant.MESSAGE_TYPE_ACTIVITY_APPLY:
                dto.setApplyVo(activityApplyMapper.selectById(entity.getBizId()));
                dto.setActivityArticle(activityArticleMapper.getArticleById(dto.getApplyVo().getArtId()));
                break;
            case ChatMessageConstant.MESSAGE_TYPE_ACTIVITY_COMMENT:
                ActivityComment comment = activityCommentMapper.getCommentById(entity.getBizId());
                if (comment != null) {
                    dto.setCommentVo(comment);
                    ActivityComment lastComment = activityCommentMapper.getCommentById(comment.getParentId());
                    if (lastComment != null) {
                        dto.setLastComment(lastComment.getContent());
                    }
                    dto.setActivityArticle(activityArticleMapper.getArticleById(comment.getArticleId()));
                }
                break;
            case ChatMessageConstant.MESSAGE_TYPE_ACTIVITY_CHAT:
                QueryWrapper<ActivityApply> applyWrapper = new QueryWrapper<>();
                applyWrapper.eq("art_id", entity.getBizId());
                applyWrapper.eq("user_id", entity.getFormUserId()).
                        or().eq("user_id", entity.getToUserId()).eq("art_id", entity.getBizId()).last("limit 1");
                dto.setApplyVo(activityApplyMapper.selectOne(applyWrapper));
                dto.setActivityArticle(activityArticleMapper.getArticleById(entity.getBizId()));
                break;
            case ChatMessageConstant.MESSAGE_TYPE_ACTIVITY_LOCATION:
                LocationDto locationDto = JSON.parseObject(entity.getLocationInfo(), LocationDto.class);
                dto.setLocationInfo(locationDto);
                break;
            case ChatMessageConstant.MESSAGE_TYPE_ACTIVITY_TRANSFER:
                dto.setRecord(transferRecordMapper.selectById(entity.getBizId()));
                break;
            case ChatMessageConstant.MESSAGE_TYPE_ACTIVITY_CARD:
                ActivityArticleDto articleDto = JSON.parseObject(entity.getCardInfo(), ActivityArticleDto.class);
                dto.setCardInfo(articleDto);
                break;
            default:
                throw new CampusException("未知的消息类型", 201);
        }
        if (dto.getActivityArticle() != null && dto.getActivityArticle().getStatus() != null && dto.getApplyVo() != null) {
            if (dto.getApplyVo().getOrdersStatus().equals("2")) {
                String status = dto.getActivityArticle().getStatus().equals("3") ? "7" : dto.getApplyVo().getOrdersStatus();
                dto.getApplyVo().setOrdersStatus(status);
            } else {
                String status = dto.getActivityArticle().getStatus().equals("3") ? "6" : dto.getApplyVo().getOrdersStatus();
                dto.getApplyVo().setOrdersStatus(status);
            }
        }
        return dto;
    }

    @Override
    public void updateDeleteFlag(String commentId) {
        LambdaUpdateWrapper<ChatMessagesEntity> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(ChatMessagesEntity::getBizId, commentId);
        updateWrapper.set(ChatMessagesEntity::getIsDelete, 1);
        update(updateWrapper);

    }


}
